#include "UIEventRouter.h"
#include "UIModule.h"
#include "UIOSAL.h"
#include "pthread.h"
#include <iostream>
#include <unistd.h>

pthread_mutex_t	m_pairedEventMutexPool[MAX_PAIR_EVENT_NUM];
pthread_cond_t	m_pairedEventWaitCondPool[MAX_PAIR_EVENT_NUM];
pthread_mutex_t	m_currentPairIDMutex;

UIEventRouter* UIEventRouter::m_pInstance = NULL;

UIEventRouter* UIEventRouter::getInstance()
{
	if (!m_pInstance)
		m_pInstance = new UIEventRouter();
	return m_pInstance;
}

void UIEventRouter::release()
{
	if (m_pInstance)
		delete m_pInstance;
	m_pInstance = NULL;
}

UIEventRouter::UIEventRouter(void)
{
	for (int i=0; i<MAX_PAIR_EVENT_NUM; i++) {
		m_pairedEventPool[i].isReturned = false;
		m_pairedEventPool[i].event = NULL;
		pthread_mutex_init(m_pairedEventMutexPool+i, NULL);
		pthread_cond_init(m_pairedEventWaitCondPool+i, NULL);
	}
	m_currentPairID = 1;
	pthread_mutex_init(&m_currentPairIDMutex, NULL);

	// Initialize Winsock
	/*
	WSADATA wsaData;
	int iResult;
	iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
	if (iResult != 0) {
		UILogger::getInstance()->err(MODULE_OTHER, "UIEventRouter", "WSAStartup failed with error: " + iResult);
		return;
	}


	if (UIConfigResourceManager::getInstance()->isLocalSocketServer()) {
		m_pSocketService = new UIEventSocketServerService();
	}
	else {
		m_pSocketService = new UIEventSocketClientService();
	}
	
	if (m_pSocketService) {
		if (m_pSocketService->initialize()) {
			m_pSocketService->startListening();
		}
		else {
			UILogger::getInstance()->err(MODULE_OTHER, "UIEventRouter", "Fail to initialize socket service");
			std::cout << "Error: Socket server not started!!!" << std::endl;
		}
	}
	else {
		UILogger::getInstance()->err(MODULE_OTHER, "UIEventRouter", "Fail to initialize socket service");
		std::cout << "Error: Socket server not started!!!" << std::endl;
	}
	*/
}

UIEventRouter::~UIEventRouter(void)
{
	for (int i=0; i<MAX_PAIR_EVENT_NUM; i++) {
		pthread_mutex_destroy(m_pairedEventMutexPool+i);
		pthread_cond_destroy(m_pairedEventWaitCondPool+i);
	}
	pthread_mutex_destroy(&m_currentPairIDMutex);

	/*
	WSACleanup();
	delete m_pSocketService;
	*/
}

void UIEventRouter::registerModule(UIModuleType type, UIModule* module)
{
	m_syncEventProcessors[type]	 = new UISyncEventProcessor(module);
	//m_asyncEventProcessors[type] = new UIAsyncEventProcessor(module);
	m_syncDataProcessors[type] = new UISyncDataProcessor(module);
}

bool UIEventRouter::isSyncEvent(UIModuleType module_type, std::string event_type)
{
	return true;
}

bool UIEventRouter::sendEvent(UIEvent* event) 
{
	if (event == 0)
		return false;

	UILogger::getInstance()->debug(MODULE_OTHER, "UIEventRouter", "Process event:\n" + event->serializeJson());

	UIEvent *copiedEvent = new UIEvent();
	event->copyTo(copiedEvent);

	// Process unpaired event
	if (copiedEvent->getPairID() == -1) {
		if (UIConfigResourceManager::getInstance()->isLocalModule(copiedEvent->m_reciever)) {
			if (m_syncEventProcessors[copiedEvent->m_reciever] == NULL)
				return false;
			if (copiedEvent->m_type.compare("cancel") == 0) {
				m_syncEventProcessors[copiedEvent->m_reciever]->cancel();
				//m_asyncEventProcessors[copiedEvent->m_reciever]->cancel();
				m_syncDataProcessors[copiedEvent->m_reciever]->cancel();
			}
			else if (isSyncEvent(copiedEvent->m_reciever, copiedEvent->m_type))
				m_syncEventProcessors[copiedEvent->m_reciever]->addEvent(copiedEvent);
			//else
				//m_asyncEventProcessors[copiedEvent->m_reciever]->processEvent(copiedEvent);
		}
		//else
			//m_pSocketService->sendEvent(copiedEvent);
	}
	else {
		UILogger::getInstance()->debug(MODULE_OTHER, "UIEventRouter", "Paired event return / ID=" + toStr(copiedEvent->getPairID()));
		int poolPosition = m_pairID2PoolIdx[copiedEvent->getPairID()];
		if (poolPosition == -1) {
			UILogger::getInstance()->err(MODULE_OTHER, "UIEventRouter", "Invalid returned pair event / ID=" + toStr(copiedEvent->getPairID()));
			return false;
		}
		pthread_mutex_lock(m_pairedEventMutexPool+poolPosition);
		if (m_pairedEventPool[poolPosition].event == NULL) {
			pthread_mutex_unlock(m_pairedEventMutexPool+poolPosition);
			UILogger::getInstance()->err(MODULE_OTHER, "UIEventRouter", "Delayed returned pair event / ID=" + toStr(copiedEvent->getPairID()));
			return false;
		}
		m_pairedEventPool[poolPosition].isReturned = true;
		copiedEvent->copyTo(m_pairedEventPool[poolPosition].event);
		pthread_mutex_unlock(m_pairedEventMutexPool+poolPosition);

		UILogger::getInstance()->debug(MODULE_OTHER, "UIEventRouter", "Start to pair event / ID=" + toStr(copiedEvent->getPairID()));
		pthread_cond_signal(m_pairedEventWaitCondPool+poolPosition);
	}
	return true;
}

bool UIEventRouter::sendSyncEvent(UIEvent* event, UIEvent& retEvent, int timeOutSecond)
{
	if (event == 0)
		return false;
	UILogger::getInstance()->debug(MODULE_OTHER, "UIEventRouter", "Process paired event:\n" + event->serializeJson());

	UIEvent *copiedEvent = new UIEvent();
	event->copyTo(copiedEvent);

	// assign a pairID
	int pairID = -1;
	pthread_mutex_lock(&m_currentPairIDMutex);
	pairID = m_currentPairID;
	m_currentPairID++;
	pthread_mutex_unlock(&m_currentPairIDMutex);
	copiedEvent->setPairID(pairID);
	
	// assign a position in a pool
	int poolPosition = -1;
	int iPool = 0;
	while (poolPosition == -1 && iPool<MAX_PAIR_EVENT_NUM) 
	{
		pthread_mutex_lock(m_pairedEventMutexPool+iPool);
		if (m_pairedEventPool[iPool].event == NULL) 
		{
			m_pairedEventPool[iPool].event = &retEvent;
			m_pairedEventPool[iPool].isReturned = false;
			m_pairID2PoolIdx[pairID] = iPool;
			poolPosition = iPool;
		}
		pthread_mutex_unlock(m_pairedEventMutexPool+iPool);
		iPool++;
	}
	if (poolPosition == -1) {
		UILogger::getInstance()->err(MODULE_OTHER, "UIEventRouter", "Paired event pool is full.");
		return false;
	}

	// send out the event
	if (UIConfigResourceManager::getInstance()->isLocalModule(copiedEvent->m_reciever)) {
		if (isSyncEvent(copiedEvent->m_reciever, copiedEvent->m_type))
			m_syncEventProcessors[copiedEvent->m_reciever]->addEvent(copiedEvent);
		//else
			//m_asyncEventProcessors[copiedEvent->m_reciever]->processEvent(copiedEvent);
	}
	//else
		//m_pSocketService->sendEvent(copiedEvent);
	UILogger::getInstance()->debug(MODULE_OTHER, "UIEventRouter", "Sent paired event / ID=" + toStr(pairID));

	// waiting for the returned event
	pthread_mutex_lock(m_pairedEventMutexPool+poolPosition);
	if (!m_pairedEventPool[poolPosition].isReturned) {
		sys_time_t curTime;
		system_time(&curTime);
		long long curTimeMSEC = time_to_msec(curTime);
		timespec timeOutTime;
		timeOutTime.tv_sec  = curTimeMSEC/1000 + timeOutSecond;
		timeOutTime.tv_nsec = curTimeMSEC%1000;
		pthread_cond_timedwait(m_pairedEventWaitCondPool+poolPosition, m_pairedEventMutexPool+poolPosition, &timeOutTime);
	}
	m_pairedEventPool[poolPosition].event = NULL;
	m_pairedEventPool[poolPosition].isReturned = false;
	pthread_mutex_unlock(m_pairedEventMutexPool+poolPosition);
	UILogger::getInstance()->debug(MODULE_OTHER, "UIEventRouter", "Successed to pair event / ID=" + toStr(pairID));
	return true;
}

bool UIEventRouter::sendData(UIEvent* event) 
{
	if (event == 0)
		return false;

	UILogger::getInstance()->debug(MODULE_OTHER, "UIEventRouter", "Process data event (data length = " + toStr(event->getDataLength()) + "):\n" + event->serializeJson());

	UIEvent *copiedEvent = new UIEvent();
	event->copyTo(copiedEvent);

	// Process unpaired event
	if (UIConfigResourceManager::getInstance()->isLocalModule(copiedEvent->m_reciever)) {
		if (copiedEvent->m_type.compare("cancel") == 0) {
			m_syncDataProcessors[copiedEvent->m_reciever]->cancel();
			m_syncEventProcessors[copiedEvent->m_reciever]->cancel();
			//m_asyncEventProcessors[copiedEvent->m_reciever]->cancel();
		}else {
			m_syncDataProcessors[copiedEvent->m_reciever]->addData(copiedEvent);
		}
	}else {
		return false;
	}
	
	return true;
}


/*----------------------------------------------------------------------------------------------------------------
Class UIAsyncEventProcessor
----------------------------------------------------------------------------------------------------------------*/
/*

UIAsyncEventProcessor::UIAsyncEventProcessor(UIModule* module):
	m_module(module)
{
	for (int i=0; i<ASYNC_EVENT_PROCESSOR_POOL_SIZE; i++)
		eventProcessThreadPool[i] = NULL;
}

UIAsyncEventProcessor::~UIAsyncEventProcessor(void)
{
	for (int i=0; i<ASYNC_EVENT_PROCESSOR_POOL_SIZE; i++) {
		eventProcessThreadPool[i]->suspend();
		eventProcessThreadPool[i]->close();
	}
}

void UIAsyncEventProcessor::cancel(void)
{
	m_module->cancel();
	for (int i=0; i<ASYNC_EVENT_PROCESSOR_POOL_SIZE; i++) {
		if (eventProcessThreadPool[i]->isRunning())
			eventProcessThreadPool[i]->suspend();
	}
}

void UIAsyncEventProcessor::processEvent(UIEvent *event)
{
	UIEventProcessorInfo taskinfo;
	taskinfo.event = event;
	taskinfo.module = m_module;

	std::string threadName = "AsyncEventProcessThread-";
	threadName.append(UIModuleTypeStrings[m_module->getType()]);
	for (int i=0; i<ASYNC_EVENT_PROCESSOR_POOL_SIZE; i++) {
		if (!eventProcessThreadPool[i]->isRunning()) {
			eventProcessThreadPool[i]->start(0, 0, asyncEventProcess, &taskinfo, 0, threadName);
			return;
		}
	}
}

unsigned __stdcall asyncEventProcess(LPVOID lpParam) {
	UIEventProcessorInfo *taskinfo = (UIEventProcessorInfo*)lpParam;
	if (taskinfo->event == 0) 
		taskinfo->module->processAsyncEvent(taskinfo->event);
	delete taskinfo->event;
	return 0;
}
*/

/*----------------------------------------------------------------------------------------------------------------
Class UISyncEventProcessor
----------------------------------------------------------------------------------------------------------------*/
UISyncEventProcessor::UISyncEventProcessor(UIModule* module):
	m_module(module)
{
	pthread_create(&eventProcessThread, NULL, syncEventProcessLoop, this);
}

UISyncEventProcessor::~UISyncEventProcessor(void)
{
	pthread_cancel(eventProcessThread);
	pthread_join(eventProcessThread, NULL);

}

UIEvent* UISyncEventProcessor::getFirstEvent(void) 
{
	if (m_eventQueue.empty())
		return 0;
	UIEvent *event = m_eventQueue.front();
	m_eventQueue.pop_front();
	return event;
}

UIModule* UISyncEventProcessor::getModule(void) 
{
	return m_module;
}

void UISyncEventProcessor::addEvent(UIEvent *event)
{
	m_eventQueue.push_back(event);
}

void UISyncEventProcessor::cancel(void)
{
	m_module->cancel();
	pthread_cancel(eventProcessThread);
	pthread_join(eventProcessThread, NULL);
	m_eventQueue.clear();
	pthread_create(&eventProcessThread, NULL, syncEventProcessLoop, NULL);
}

void* syncEventProcessLoop(void* lpParam) {
	UISyncEventProcessor *processor = (UISyncEventProcessor*)lpParam;

	while (true) {
		UIEvent *event = processor->getFirstEvent();
		while(event == 0) {
			pthread_testcancel();
			usleep(200000);
			event = processor->getFirstEvent();
		}
		pthread_testcancel();
		processor->getModule()->processSyncEvent(event);
		delete event;
	}
	return 0;
}

/*----------------------------------------------------------------------------------------------------------------
Class UISyncDataProcessor
----------------------------------------------------------------------------------------------------------------*/
UISyncDataProcessor::UISyncDataProcessor(UIModule* module):
	m_module(module)
{
	pthread_create(&dataProcessThread, NULL, syncDataProcessLoop, this);
}

UISyncDataProcessor::~UISyncDataProcessor(void)
{
	pthread_cancel(dataProcessThread);
	pthread_join(dataProcessThread, NULL);
}

UIEvent* UISyncDataProcessor::getFirstData(void) 
{
	if (m_dataQueue.empty())
		return 0;
	UIEvent *event = m_dataQueue.front();
	m_dataQueue.pop_front();
	return event;
}

UIModule* UISyncDataProcessor::getModule(void) 
{
	return m_module;
}

void UISyncDataProcessor::addData(UIEvent *event)
{
	m_dataQueue.push_back(event);
}

void UISyncDataProcessor::cancel(void)
{
	m_module->cancel();
	pthread_cancel(dataProcessThread);
	pthread_join(dataProcessThread, NULL);
	m_dataQueue.clear();
	pthread_create(&dataProcessThread, NULL, syncDataProcessLoop, NULL);
}

void* syncDataProcessLoop(void* lpParam) {
	UISyncDataProcessor *processor = (UISyncDataProcessor*)lpParam;

	while (true) {
		UIEvent *event = processor->getFirstData();
		while(event == 0) {
			pthread_testcancel();
			usleep(200000);
			event = processor->getFirstData();
		}
		pthread_testcancel();
		processor->getModule()->processData(event);
		event->deleteData();
		delete event;
	}
	return 0;
}

/*----------------------------------------------------------------------------------------------------------------
Class UIEventSocketService
----------------------------------------------------------------------------------------------------------------*/
/*
UIEventSocketService::UIEventSocketService()
{
}

UIEventSocketService::~UIEventSocketService()
{
}

int UIEventSocketService::sendAll(SOCKET socket, char *data, int* len)
{
	int total = 0; // how many bytes we've sent
	int bytesleft = *len; // how many we have left to send
	int n;
	while(total < *len) {
		n = send(socket, data+total, bytesleft, 0);
		if (n == -1) { break; }
		total += n;
		bytesleft -= n;
	}
	*len = total; // return number actually sent here
	return n==-1?-1:0; // return -1 on failure, 0 on success
}

int UIEventSocketService::genData(UIEvent* event, UISocketMessage* message)
{
	std::string jsonString = event->serializeJson();
	message->type(2);
	message->time(event->getTimeStamp());
	message->body_length(jsonString.length());
	memcpy(message->body(), jsonString.c_str(), message->body_length());
	message->encode_header();
	return message->length();
}
*/

/*----------------------------------------------------------------------------------------------------------------
Class UIEventSocketClientService
----------------------------------------------------------------------------------------------------------------*/
/*
UIEventSocketClientService::UIEventSocketClientService()
{
	m_Socket = INVALID_SOCKET;
}

UIEventSocketClientService::~UIEventSocketClientService()
{
	if (m_Socket != INVALID_SOCKET) 
	{
		closesocket(m_Socket);
		if (listeningThread.isRunning()) {
			listeningThread.suspend();
			listeningThread.close();
		}
	}
}

bool UIEventSocketClientService::initialize(void)
{
	struct addrinfo hints;
	struct addrinfo *result = NULL;

	memset(&hints, 0, sizeof(hints));
	hints.ai_family		= AF_UNSPEC;
	hints.ai_socktype	= SOCK_STREAM;
	hints.ai_protocol	= IPPROTO_TCP;

	std::string serverAddr = UIConfigResourceManager::getInstance()->getSocketServerAddr();
	std::string serverPort = toStr(UIConfigResourceManager::getInstance()->getSocketServerPort());

	int iResult;
	iResult = getaddrinfo(serverAddr.c_str(), serverPort.c_str(), &hints, &result);
	if ( iResult != 0 ) {
		UILogger::getInstance()->err(MODULE_OTHER, "UIEventSocketClientService", "Fail to get socket server address: " + iResult);
		return false;
	}

	// Attempt to connect to an address until one succeeds
	for( struct addrinfo *ptr = result; ptr != NULL; ptr=ptr->ai_next) {
		// Create a SOCKET for connecting to server
		m_Socket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
		if (m_Socket == INVALID_SOCKET) {
			UILogger::getInstance()->err(MODULE_OTHER, "UIEventSocketClientService", "socket failed with error: " + WSAGetLastError());
			freeaddrinfo(result);
			return false;
		}

		// Connect to server.
		iResult = connect(m_Socket, ptr->ai_addr, (int)ptr->ai_addrlen);
		if (iResult == SOCKET_ERROR) {
			closesocket(m_Socket);
			m_Socket = INVALID_SOCKET;
			continue;
		}
		break;
	}
	freeaddrinfo(result);

	if (m_Socket == INVALID_SOCKET)
	{
		UILogger::getInstance()->err(MODULE_OTHER, "UIEventSocketClientService", "Unable to connect to socket server: " + WSAGetLastError());
		return false;
	}

	return true;
}

void UIEventSocketClientService::startListening(void)
{
	std::string threadName = "SocketListeningThread-Client";
	listeningThread.start(0, 0, socketListening, &m_Socket, 0, threadName);
}

void UIEventSocketClientService::sendEvent(UIEvent* event)
{
	UISocketMessage message;
	int len = genData(event, &message);
	int sentLen = len;
	if (sendAll(m_Socket, message.data(), &sentLen) == -1) 
	{
		UILogger::getInstance()->err(MODULE_OTHER, "UIEventSocketClientService", 
			"Unable to send complete socket message: " + toStr(sentLen) + "/" + toStr(len));
	}
	delete event;
}
*/

/*----------------------------------------------------------------------------------------------------------------
Class UIEventSocketServerService
----------------------------------------------------------------------------------------------------------------*/
/*
UIEventSocketServerService::UIEventSocketServerService()
{
	m_listenSocket = INVALID_SOCKET;
}

UIEventSocketServerService::~UIEventSocketServerService()
{
	if (m_listenSocket != INVALID_SOCKET)
		closesocket(m_listenSocket);

	if (acceptThread.isRunning()) {
		acceptThread.suspend();
		acceptThread.close();
	}

	for (std::map<std::string, SOCKET>::iterator iteSocket = m_clientSockets.begin(); iteSocket != m_clientSockets.end(); iteSocket++) {
		closesocket(iteSocket->second);
		if (m_listeningThreads[iteSocket->first].isRunning()) {
			m_listeningThreads[iteSocket->first].suspend();
			m_listeningThreads[iteSocket->first].close();
		}
	}
}

bool UIEventSocketServerService::initialize(void)
{
	struct addrinfo hints;
	struct addrinfo *result = NULL;

	memset(&hints, 0, sizeof(hints));
	hints.ai_family		= AF_INET;
	hints.ai_socktype	= SOCK_STREAM;
	hints.ai_protocol	= IPPROTO_TCP;
	hints.ai_flags		= AI_PASSIVE;

	std::string serverPort = toStr(UIConfigResourceManager::getInstance()->getSocketServerPort());

	// Resolve the server address and port
	int iResult;
	iResult = getaddrinfo(NULL, serverPort.c_str(), &hints, &result);
	if ( iResult != 0 ) {
		UILogger::getInstance()->err(MODULE_OTHER, "UIEventSocketServerService", "Fail to get socket server address: " + iResult);
		return false;
	}

	// Create and setup SOCKET for connecting to server
	m_listenSocket =  socket(result->ai_family, result->ai_socktype, result->ai_protocol);
	if (m_listenSocket == INVALID_SOCKET) {
		UILogger::getInstance()->err(MODULE_OTHER, "UIEventSocketServerService", "Fail to create a listening socket: " + WSAGetLastError());
		freeaddrinfo(result);
		return false;
	}
	iResult = bind( m_listenSocket, result->ai_addr, (int)result->ai_addrlen);
	if (iResult == SOCKET_ERROR) {
		UILogger::getInstance()->err(MODULE_OTHER, "UIEventSocketServerService", "Fail to bind a listeing socket: " + WSAGetLastError());
		freeaddrinfo(result);
		closesocket(m_listenSocket);
		m_listenSocket = INVALID_SOCKET;
		return false;
	}
	freeaddrinfo(result);

	iResult = listen(m_listenSocket, SOMAXCONN);
	if (iResult == SOCKET_ERROR) {
		UILogger::getInstance()->err(MODULE_OTHER, "UIEventSocketServerService", "Listen failed with error: " + WSAGetLastError());
		closesocket(m_listenSocket);
		m_listenSocket = INVALID_SOCKET;
		return false;
	}

	return true;
}

void UIEventSocketServerService::sendEvent(UIEvent* event)
{
	//std::string recieverAddr = UIConfigResourceManager::getInstance()->getModuleAddress(event->getReciever());
	std::map<UIModuleType, std::string>::iterator itModule;
	itModule = m_moduleAddr.find(event->getReciever());
	if (itModule == m_moduleAddr.end()) {
		UILogger::getInstance()->err(
			MODULE_OTHER, "UIEventSocketServerService", 
			"Remote module not registered: " + getModuleName(event->getReciever()));
		delete event;
		return;
	}
	
	std::map<std::string, SOCKET>::iterator itAddr;
	itAddr = m_clientSockets.find(itModule->second);
	if (itAddr == m_clientSockets.end()) {
		UILogger::getInstance()->err(
			MODULE_OTHER, "UIEventSocketServerService", 
			"No socket connection with remote module: " + getModuleName(event->getReciever()) + "/" + itModule->second);
		delete event;
		return;
	}

	UISocketMessage message;
	int len = genData(event, &message);
	int sentLen = len;
	if (sendAll(itAddr->second, message.data(), &sentLen) == -1) 
	{
		UILogger::getInstance()->err(MODULE_OTHER, "UIEventSocketServerService", 
			"Unable to send complete socket message: " + toStr(sentLen) + "/" + toStr(len));
	}
	delete event;
}

void UIEventSocketServerService::startListening(void)
{
	std::string threadName = "AcceptThread-Server";
	acceptThread.start(0, 0, clientSocketAccept, this, 0, threadName);
}

typedef struct {
	UIEventSocketServerService *pService;
	SOCKET* pSocket;
	char addr[64];
} SocketServiceListeningPara;

void UIEventSocketServerService::addSocket(std::string addr, SOCKET socket)
{
	m_clientSockets[addr] = socket;
	std::string threadName = "SocketListeningThread-Server-"+addr;
	SocketServiceListeningPara *para = new SocketServiceListeningPara();
	para->pService = this;
	para->pSocket = &m_clientSockets[addr];
	strcpy(para->addr, addr.c_str());
	m_listeningThreads[addr].start(0, 0, socketListening, para, 0, threadName);
}

unsigned __stdcall socketListening(LPVOID lpParam) {
	SocketServiceListeningPara *para = (SocketServiceListeningPara*) lpParam;
	SOCKET* pSocket = para->pSocket;
	UIEventSocketServerService* pService = para->pService;
	std::string addr(para->addr);
	delete para;
	
	if (*pSocket != INVALID_SOCKET) {
		int iResult;
		do {
			int recvlen = 0;
			UISocketMessage message;

			// recieve message head
			do {
				iResult = recv(*pSocket, message.data(recvlen), message.header_length-recvlen, 0);
				if (iResult > 0) {
					recvlen += iResult;
				}
				else if ( iResult == 0 ) {
					UILogger::getInstance()->warn(MODULE_OTHER, "socketListening", "Connection closed when recieving data header");
					*pSocket = INVALID_SOCKET;
				}
				else {
					UILogger::getInstance()->err(MODULE_OTHER, "socketListening", "Recieving data header failed with error: " + WSAGetLastError());
					closesocket(*pSocket);
					*pSocket = INVALID_SOCKET;
				}
			}	while (recvlen < message.header_length && iResult > 0);

			// recieve message body
			if (recvlen == message.header_length) {
				message.decode_header();
				recvlen = 0;
				if (message.body_length() > 0) {
					do {
						iResult = recv(*pSocket, message.body(recvlen), message.body_length()-recvlen, 0);
						if (iResult > 0) {
							recvlen += iResult;
						}
						else if ( iResult == 0 ) {
							UILogger::getInstance()->warn(MODULE_OTHER, "socketListening", "Connection closed when recieving data");
							*pSocket = INVALID_SOCKET;
						}
						else {
							UILogger::getInstance()->err(MODULE_OTHER, "socketListening", "Recieving data failed with error: " + WSAGetLastError());
							closesocket(*pSocket);
							*pSocket = INVALID_SOCKET;
						}
					} while (recvlen < message.body_length() && iResult > 0);

					if (recvlen == message.body_length()) {
						std::string jsonMessage(message.body(), message.body_length());
						UIEvent event;
						event.deserializeJson(jsonMessage);

						// Process remote module registration event
						if (event.getReciever() == MODULE_EventRouter) 
						{
							if (event.getType().compare("registration") == 0) {
								pService->addModuleAddr(event.getSender(), addr);
								UILogger::getInstance()->inf(MODULE_OTHER, "socketListening", "Remote module registered: " + getModuleName(event.getSender()) + "@" + addr);
							}
						}
						else {
							UIEventRouter::getInstance()->sendEvent(&event);
						}
					}
				}
			}
		} while( iResult > 0 );
	}
	return 0;
}

unsigned __stdcall clientSocketAccept(LPVOID lpParam)
{
	UIEventSocketServerService* socketServer = (UIEventSocketServerService*)lpParam;
	while (socketServer->m_listenSocket != INVALID_SOCKET) {
		struct sockaddr_in clientAddr;
		int len = sizeof(clientAddr);
		SOCKET client = accept(socketServer->m_listenSocket, (struct sockaddr *)&clientAddr, &len);
		if (client == INVALID_SOCKET) {
			UILogger::getInstance()->err(MODULE_OTHER, "UIEventSocketServerService", "accept failed with error: " + WSAGetLastError());
			closesocket(socketServer->m_listenSocket);
			socketServer->m_listenSocket = INVALID_SOCKET;
		}
		else {
			std::string strClientAddr = inet_ntoa(clientAddr.sin_addr);
			UILogger::getInstance()->inf(MODULE_OTHER, "UIEventSocketServerService", "client connected: "+strClientAddr);
			if (!equalsIgnoreCase(strClientAddr, "")) {
				socketServer->addSocket(strClientAddr, client);
			}
		}
	}
	return 0;
}
*/
